A Dynamic Link Library (“DLL”) represents a very powerful and efficient way for applications to share code and data. A DLL is an executable library module containing functions or resources for use by applications or other DLLs. Unlike typical programs however, DLLs do not have a single entry point. Instead, like libraries, DLLs can have multiple entry points, one for each exported subroutine (“Subroutine”) or function (“Function”).
Static linking is known to those of ordinary skill in the art as the process of writing one or more modules and then linking them to create a complete, stand-alone executable program. When a program uses a Subroutine or Function from a library, a copy of that Subroutine or Function's code is added to the program's executable file. If two programs are running simultaneously and use the same Subroutine or Function, there will be two copies of that routine present in memory. It would be more efficient in terms of memory usage if the two programs could share a single copy of the routine. DLLs provide that ability.
In contrast to static linking, dynamic linking using DLLs provides a mechanism to link applications to libraries at run-time. Unlike a static library, the code in a DLL is not included into the program that uses the DLL. Instead, a DLL's code and resources are in a separate file (usually with a .DLL extension). This file must be either currently loaded in memory or accessible to the operating system when the program that uses the DLL executes. To access the individual procedures in a DLL, a DECLARE statement is typically included in the program code with the name of the Subroutine or Function and the name of the DLL.
Unlike conventional libraries, when a DLL is loaded into memory by the operating system, its procedures are accessible by all other programs (or DLLs). Only one copy of the DLL needs to be present in memory. This is possible because the library is not linked into any one of the programs permanently. It is simply present in memory, making its services available to any code that may need them.
Before a Function or Subroutine in a DLL can be used, the DLL must first be loaded into memory. Such loading is typically performed using one of two approaches. Under one approach, most of the linking takes place at compilation time and the “dynamic linking” that takes place during run-time is typically restricted to the resolution of symbols. An application that uses a DLL is typically unaware of the provenance of the resolved symbols. To use this approach, a Function or Subroutine that resides in the DLL is typically declared with the “external” keyword. The DLL is automatically loaded when the application loads, and any functions or procedures exported from the DLL can then be called just as any other Function or Subroutine would be called. This is by far the easiest way to use code contained in a DLL. The disadvantage to this approach is that if a DLL that the program references is missing, the program will refuse to load.
Under the second approach a DLL is only loaded into memory when needed and unloaded from memory when it is no longer needed. One advantage of this approach is that the DLL is in memory only as long as it is needed, resulting in more efficient use of memory. Another advantage is that applications will typically load more quickly when using this approach because not all the code needed to run the program is loaded when the application initially loads.
In DLL collections of software modules, a first software module that references an external Subroutine or Function typically knows the identity or name of a second software module that contains the referenced Subroutine or Function and is thus required for the execution of the first software module. However, there are situations where the first software module knows a property required for the execution of the first software module, but does not know the name of the software module that includes that property.
A chassis management software program provides an example of such a situation. A network computer contains a number of hardware devices connected together via the network. The hardware devices may be housed in a chassis configured with one or more ports to accept various types of modular hardware devices. In such a system, a particular port adapter driver DLL is typically required to interface between the chassis management program and each hardware device. Each hardware device normally contains identification information for the device. This information is usually stored on a programmable read only memory chip (PROM) but any number of non-volatile memory storage media are possible. When the memory device is in PROM, it is usually referred to as the identifier (ID) PROM of the device. The type of information stored on each of these devices usually includes identification information such as the device's serial number or its part number.
When a new hardware device is added, a chassis driver software module within the chassis management program must load the DLL that includes the port adapter driver required to interface with the hardware device. In this case, the chassis driver knows the required property of the driver is the PROM ID of the inserted hardware device. That is, the chassis driver knows it must load a port adapter driver that is compatible with the hardware device identified by the PROM ID.
In order to load the appropriate port adapter driver, the chassis driver needs to know the name of the DLL that includes the port adapter driver for the hardware device. In such cases, the PROM ID of the hardware device is typically encoded in the name of the DLL that includes the port adapter driver for the hardware device. This information is typically hard-coded in a table. Thus, the chassis driver reads the PROM ID of the newly inserted hardware device, forms the DLL name based on the PROM ID and loads the DLL. This process is described below with reference to FIG. 1.
FIG. 1 is a flow diagram that illustrates a typical method for dynamically loading a DLL required for a new hardware device. At 100, a table that maps a hardware device PROM ID to the name of the DLL that includes port adapter driver software for the hardware device is created. The table is typically hard-coded in a chassis management program. The chassis management program includes a chassis driver software module that handles the addition of new hardware. At 105, a determination is made regarding whether a new hardware device has been detected. If a new hardware device has been detected, at 110 the chassis driver reads a register of the new hardware device to obtain the hardware device PROM ID. At 115, the name of the DLL including the port adapter driver for the new hardware device is obtained from the table using the PROM ID obtained at 110. At 120, the DLL including port adapter driver for the new hardware device is loaded, allowing a chassis management program to interface with the device.
However, a port adapter driver can drive hardware with different PROM IDs. A port adapter driver can also drive hardware devices on different platforms. Additionally, the hardware device and/or the associated port adapter driver may not exist when the chassis is made. PROM ID-to-DLL name encoding method described above supports none of these scenarios.
What is needed is solution that enables execution of a computer program where the identity of a required module is discovered dynamically during program execution. A further need exists for such a solution that uses open and well-understood standards.